from models import *
from django.template.loader import render_to_string

def prepare_html_schedule(schedule, iternum):
    """
    Take the data of a schedule and return an HTML <table> that
    will display it like a time table.
    Steps:
        1) Take all the CourseSlots in the table and stick them
        in a structured list of dictionaries. The structured dictionaries
        include entries for blank cells. Important: rowspans need to be
        calculated, which allows a CourseSlot to span multiple rows (every
        CourseSlot does, so this needs to be done correctly.)
        2) Renders it using the 'schedule.html' template. This is good because
        we do not mix code with HTML. We still do in the generate() view
        function, but that stuff is trivial. (Yes, it still shouldn't
        be there.)
    """
    import datetime
    from math import floor, ceil
    block_size = 15

    def minutes(dtt):
        """How many minutes is the time since the beginning of the day (i.e. midnight)?"""
        ret = dtt.hour*60 + dtt.minute
        return ret

    def get_start_block(c):
        return int(floor(minutes(c.begin_time)/block_size))

    # go from 8:45am to 11pm
    start_block = datetime.time(hour=8, minute=45)
    start_blockblock = int(minutes(start_block) / block_size)
    end_block = datetime.time(hour=23, minute=0)
    total_blocks = (minutes(end_block) - minutes(start_block)) / block_size

    # how many blocks does an item take up on the schedule?
    def get_num_blocks(courseslot):
        end_time_min = minutes(courseslot.end_time)
        begin_time_min = minutes(courseslot.begin_time)
        dif = end_time_min - begin_time_min
        return int(ceil(float(dif)/block_size))

    sched_data = schedule.get_output_data()

    times = []
    time_counter = start_block
    # get all the times for the left-hand time column
    for i in range(total_blocks):
        times.append(time_counter.strftime('%H:%M'))
        try:
            time_counter = time_counter.replace(minute=time_counter.minute+15)
        except ValueError:
            time_counter = time_counter.replace(hour=time_counter.hour + 1, minute=0)

    html = ""
    trs = []

    # this is so that we get classes course1, course2, etc. on our 
    # <td>s
    courses = {}
    for cs in schedule.get_all_course_slots():
        course = cs.get_course()
        courses[course.pk] = course
    course_serialized = courses.values()

    # go through all the rows and figure out which <td>s to put where
    # (Rendering to be done afterwards)
    current_rowspans = {}
    for rownum, blocknum in enumerate(range(start_blockblock, total_blocks + start_blockblock)):
        tds = []
        tds.append({
            'data': times[rownum],
        })
        for day_index, day in enumerate(sched_data):
            for cs in day:
                if get_start_block(cs) == blocknum:
                    # how many rows does the courseslot take up on the schedule?
                    num_blocks = get_num_blocks(cs)

                    td_data = {
                        'course': cs.get_course(),
                        'coursename': str(cs.get_course()),
                        'section': cs.get_section(),
                        'sectioncode': str(cs.get_section().section_code),
                        'cs': cs,
                    }
                    # this is so that we get classes course1, course2, course3 etc..
                    course_index = course_serialized.index(cs.get_course())
                    tds.append({
                        'data': td_data,
                        'class': 'course' + str(course_index),
                        'rowspan': num_blocks
                    })
                    current_rowspans[day_index] = {
                        'start': blocknum,
                        'end': blocknum + num_blocks
                    }
                    break
            # figure out whether or not we need to add a blank cell
            # (are we 'rowspanning'?)
            if current_rowspans.has_key(day_index):
                if current_rowspans[day_index] is None:
                    add_blank = True
                else:
                    add_blank = blocknum >= current_rowspans[day_index]['end']
                    if add_blank:
                        current_rowspans[day_index] = None
            else:
                add_blank = True
            if add_blank:
                tds.append({
                    'data': '',
                })

        trs.append(tds)

    # return the rendered table
    return render_to_string('schedule.html', {'trs' : trs, 'iternum': iternum+1, 'backnum': iternum-1})

